package com.example.jdk8.interface_test;

import com.example.jdk8.person.Person;

import java.util.Comparator;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class PredicatesTest {
    public static void main(String[] args) {
        /**
         * Predicate是一个布尔类型的函数，该函数只有一个输入参数。
         * Predicate接口包含了多种默认方法，用于处理复杂的逻辑动词（and, or，negate）
         */
        Predicate<String> predicate = (s) -> s.length() > 0;
        predicate.test("foo"); // true
        predicate.negate().test("foo"); // false

        Predicate<Boolean> nonNull = Objects::nonNull;
        Predicate<Boolean> isnull = Objects::isNull;

        Predicate<String> isEmpty = String::isEmpty;
        Predicate<String> isNotEmpty = isEmpty.negate();

        /**
         * Function接口接收一个参数，并返回单一的结果。
         * 默认方法可以将多个函数串在一起（compse, andThen）
         */
        Function<String, Integer> toInteger = Integer::valueOf;
        Function<String, String> andThen = toInteger.andThen(String::valueOf);
        andThen.apply("123"); // "123"

        /**
         * Supplier接口产生一个给定类型的结果。与Function不同的是，Supplier没有输入参数
         */
        Supplier<Person> supplyPerson = Person::new;
        Person person = supplyPerson.get(); // new Person

        /**
         * Consumer代表了在一个输入参数上需要进行的操作。
         */
        Consumer<Person> consumer = (p) -> System.out.println("hello" + p.getFirstName());
        consumer.accept(new Person("luka", "balaclava"));

        /**
         * Comparator接口在早期的Java版本中非常著名。Java 8 为这个接口添加了不同的默认方法
         */
        Comparator<Person> comparator = Comparator.comparing(Person::getFirstName);
        Person p1 = new Person("John", "Doe");
        Person p2 = new Person("Alice", "Wonderland");
        comparator.compare(p1, p2); // >0
        comparator.reversed().compare(p1, p2); // <0

        /**
         * Optional不是一个函数式接口，而是一个精巧的工具接口，用来防止NullPointerException产生。
         *
         * Optional是一个简单的值容器，这个值可以是null，也可以是non-null。考虑到一个方法可能会返回一个non-null的值，
         * 也可能返回一个空值。为了不直接返回null，我们在Java 8中就返回一个Optional.
         */
        Optional<String> optional = Optional.of("bam");
        optional.orElse("fallback"); // bam
        optional.get(); // bam
        optional.isPresent(); //true
        optional.ifPresent((s -> System.out.println(s.charAt(0)))); // b
    }
}
